﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Collections;


namespace distrilan
{
  /// <summary>
  /// Gestisce la parte di caricamento degli articoli
  /// </summary>
  public class AdminCsvArticoli
  {    
    /// <summary>
    /// Funzione principale caricamento articoli
    /// </summary>
    /// <param name="fileName"></param>
    /// <returns></returns>
    static public String CaricamentoArticoli(String fileName, String fileNameIndice)
    {
      String output="";
      SqlConnection connection = new SqlConnection(Utility.GetDBConnectionString());
      SqlTransaction tr = null;

      try
      {
        // Apro la connessione verso il DB  
        connection.Open();
        tr = connection.BeginTransaction();

        // Cancello i vecchi dati presenti
        CancellaTabelle(connection, tr, ref output);
        // Leggo il file indice articoli
        ArrayList arrIndice = LetturaIndice(fileNameIndice, ref output);  
                              
        // Carico in memoria e nel database il dizionario di lettura
        Dictionary<String, String[]> dizionario = ScritturaIndice(connection,tr,arrIndice, ref output);

        // Carico nel database le famiglie, i vendors, i gruppi e le categorie
        Dictionary<String, int> famiglie = CaricaTab(connection, tr, dizionario, "famiglia" ,ref output);
        Dictionary<String, int> vendors = CaricaTab(connection, tr, dizionario, "vendor", ref output);
        Dictionary<String, int> gruppi = CaricaTab(connection, tr, dizionario, "gruppo", ref output);
        Dictionary<String, int> categorie = CaricaTab(connection, tr, dizionario, "categoria", ref output);

        // Ora leggo il file degli articoli
        ArrayList arrArt = LetturaArticoli(fileName, ref output);                                

        // Ora procedo con il caricamento articoli
        CaricaArticoli(connection, tr, dizionario, famiglie,vendors,gruppi,categorie, arrArt,ref output);

        // Vado poi a scrivere le tabelle di precalcolo del numero degli articoli
        CaricaTabellePreCalcolo(connection, tr, ref output);

        tr.Commit();
        output += "Caricamento Avvenuto con successo!";
      }
      catch (Exception)
      {
        if (tr != null) tr.Rollback();                
      }
      finally
      {
        connection.Close();
      }
      

      return output;
    }

    /// <summary>
    /// carica gli articoli nel db
    /// </summary>
    /// <param name="connection"></param>
    /// <param name="tr"></param>
    /// <param name="dizionario"></param>
    /// <param name="famiglie"></param>
    /// <param name="vendors"></param>
    /// <param name="gruppi"></param>
    /// <param name="categorie"></param>
    /// <param name="lista"></param>
    /// <param name="output"></param>
    static private void CaricaArticoli(SqlConnection connection, SqlTransaction tr, Dictionary<String, String[]> dizionario, Dictionary<String, int> famiglie, Dictionary<String, int> vendors, Dictionary<String, int> gruppi, Dictionary<String, int> categorie, ArrayList lista, ref String output)
    {      
      int count = 0;
      int riga = 0;
      String query = "";            
      SqlCommand cmd = null;
      try
      {
        // Elimino il primo elemento che rappresenta le prime colonne
        lista.RemoveAt(0);
		
        // Per ogni riga letta dal DB
        foreach (String str in lista)
        {
          // Incremento il numero di riga
          riga++;
		  
          // Spezzo il listato in campi
          String[] campi = str.Split(new char[] { ';' });
          
          // Verifico che i campi siano 5
          if (campi.Length != 5)
          {
            Utility.WriteLog("ERRORE", "CaricaArticoli", "Riga " + riga + ":la struttura della riga è errata", SiteUser.getUser().Username, str);
            output += "Si è verificato un errore durante l'elaborazione della riga " + riga + " del file articoli: Struttura della riga errata\n";
            continue;
          }

          // Dove c'era $semicolon$ rimetto il ; e tolgo gli spazi;
          for (int i = 0; i < campi.Length; i++)
          {
            campi[i] = campi[i].Replace("$semicolon$", ";").Replace("'", "''").Trim();
          }

          // Leggo i dati
          String codice = campi[0];
          String descrizione = campi[1];
          String note = campi[2];
          String prz = campi[3];
          String sottocategoria = campi[4];


          // Controllo che il prezzo vada bene
          String prezzo = "0.0";
          try{
            prezzo = Utility.GetDoubleForDB(Convert.ToDouble(prz));
          }
          catch (Exception)
          {
            Utility.WriteLog("ERRORE", "ListaArticoli", "La riga " + riga + " ha il prezzo vuoto o scritto in modo errato", SiteUser.getUser().Username, "");
            output += "WARNING: La riga " + riga + " ha il prezzo vuoto o scritto in modo errato\n";            
          }

          // Ora controllo se la sottocategoria dell'articolo esiste nel DB
          int idcat=-1;
         
          // Ora leggo dalla tabella l'id del dato appena caricato
          query = "SELECT COUNT(*) FROM sottocategoria WHERE nome='" + sottocategoria + "'";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          if (Convert.ToInt32(cmd.ExecuteScalar()) != 0)
          {
            query = "SELECT id FROM sottocategoria WHERE nome='" + sottocategoria + "'";
            cmd = new SqlCommand(query, connection);
            cmd.Transaction = tr;
            idcat = Convert.ToInt32(cmd.ExecuteScalar());
          }
          else
          {
            // Se non esiste la creo e leggo l'id            
            query = "INSERT INTO sottocategoria (nome) VALUES ('" + sottocategoria + "')";
            cmd = new SqlCommand(query, connection);
            cmd.Transaction = tr;
            cmd.ExecuteNonQuery();

            query = "SELECT id FROM sottocategoria WHERE nome='" + sottocategoria + "'";
            cmd = new SqlCommand(query, connection);
            cmd.Transaction = tr;
            idcat = Convert.ToInt32(cmd.ExecuteScalar());
          }
          

          // Leggo i primi 4 campi del codice che mi identificano i dati aggiuntivi dell'articolo
          String coddiz = "";
          String famiglia = "";
          String gruppo = "";
          String categoria = "";
          String vendor = "";
          try
          {
            coddiz = codice.Substring(0, 4);
            famiglia = dizionario[coddiz][0];
            gruppo = dizionario[coddiz][1];
            categoria = dizionario[coddiz][2];
            vendor = dizionario[coddiz][3];
          }
          catch (Exception)
          {
            Utility.WriteLog("ERRORE", "CaricaArticoli", "Riga " + riga + ":Codice articolo senza corrispondenza nell'indice articoli", SiteUser.getUser().Username, str);
            output += "Si è verificato un errore durante l'elaborazione della riga " + riga + " del file articoli: Codice articolo senza corrispondenza nell'indice articoli\n";
            continue;
          }

          // Ora scrivo l'articolo nel database
          query = "INSERT INTO articolo(codart,descri,note,prezzo,vendor,famiglia,gruppo,categoria,sottocategoria) VALUES (";
          query += "'" + codice + "','" + descrizione + "','" + note + "'," + prezzo + "," + vendors[vendor] + "," + famiglie[famiglia] + "," + gruppi[gruppo] + "," + categorie[categoria] + ","+idcat+")";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          try
          {
            cmd.ExecuteNonQuery();
          }
          catch (SqlException sqlex)
          {
            if (sqlex.Message.Contains("Violation of PRIMARY KEY constraint"))
            {
              Utility.WriteLog("ERRORE", "CaricaArticoli", "Riga " + riga + ":Codice articolo duplicato", SiteUser.getUser().Username, str);
              output += "Si è verificato un errore durante l'elaborazione della riga " + riga + " del file articoli: Codice articolo duplicato\n";
              continue;
            }
            throw sqlex;
          }

          count++;
        }
        

        if (count > 0)
        {
          output += "Caricati " + count + " Articoli\n";          
        }
        else
        {
          output += "Non è stata individuata alcuna riga valida nel file articoli\n";
          throw new Exception("Nessuna Riga Valida nel file!");
        }
      }
      catch (Exception ex)
      {
        Utility.WriteLog("ERRORE", "CaricaArticoli", ex.Message, SiteUser.getUser().Username, "");
        output += "Si è verificato un errore irreversibile durante l'elaborazione della riga " + riga + " del file articoli:"+ex.Message+"\n";
        throw ex;
      }      
    }


    static private void CaricaTabellePreCalcolo(SqlConnection connection, SqlTransaction tr, ref String output)
    {
      String query = "SELECT * FROM articolo";
      SqlCommand cmd;
      
      Dictionary<String,int> famiglie = new Dictionary<String,int>();
      Dictionary<String, int> vendors = new Dictionary<String, int>();
      Dictionary<String, int> famiglie_gruppi = new Dictionary<String, int>();
      Dictionary<String, int> vendors_gruppi = new Dictionary<String, int>();
      Dictionary<String, int> famiglie_grup_cat = new Dictionary<String, int>();
      Dictionary<String, int> vendors_grup_cat = new Dictionary<String, int>();
      Dictionary<String, int> famiglie_grup_cat_sottocat = new Dictionary<String, int>();
      Dictionary<String, int> vendors_grup_cat_sottocat = new Dictionary<String, int>();
      
      try
      {
        // Leggo tutti gli articoli scritti
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = new SqlCommand(query, connection);
        adapter.SelectCommand.Transaction = tr;
        DataSet ds = new DataSet();
        adapter.Fill(ds);
        // Scorro riga per riga memorizzando i dati
        foreach (DataRow row in ds.Tables[0].Rows)
        {
          String famiglia = row["famiglia"].ToString();
          String vendor = row["vendor"].ToString();
          String gruppo = row["gruppo"].ToString();
          String categoria = row["categoria"].ToString();
          String sottocategoria = row["sottocategoria"].ToString();

          // Incremento il conteggio del numero di articoli
          addToCount(ref famiglie, famiglia);
          addToCount(ref vendors, vendor);
          addToCount(ref famiglie_gruppi, famiglia + "$" + gruppo);
          addToCount(ref vendors_gruppi, vendor + "$" + gruppo);
          addToCount(ref famiglie_grup_cat, famiglia + "$" + gruppo + "$" + categoria);
          addToCount(ref vendors_grup_cat, vendor + "$" + gruppo + "$" + categoria);
          addToCount(ref famiglie_grup_cat_sottocat, famiglia + "$" + gruppo + "$" + categoria + "$" + sottocategoria);
          addToCount(ref vendors_grup_cat_sottocat, vendor + "$" + gruppo + "$" + categoria+"$"+sottocategoria);          
        }

        // Ok ora ho i conteggi fatti devo andarli a scrivere nel DB
        //Comincio dalle famiglie
        foreach (String key in famiglie.Keys)
        {          
          query = "UPDATE famiglia SET num_art=" + famiglie[key] + " WHERE id=" + key + "";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();          
        }
        // Poi i vendors
        foreach (String key in vendors.Keys)
        {
          query = "UPDATE vendor SET num_art=" + vendors[key] + " WHERE id=" + key + "";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }

        // famiglie_gruppi
        foreach (String key in famiglie_gruppi.Keys)
        {
          String[] vals = key.Split(new char[] { '$' });
          query = "INSERT famiglia_gruppo (famiglia,gruppo,num_art) VALUES (" + vals[0] + "," + vals[1] + "," + famiglie_gruppi[key]+ ")";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }

        // vendors_gruppi
        foreach (String key in vendors_gruppi.Keys)
        {
          String[] vals = key.Split(new char[] { '$' });
          query = "INSERT vendor_gruppo (vendor,gruppo,num_art) VALUES (" + vals[0] + "," + vals[1] + "," + vendors_gruppi[key] + ")";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }

        // famiglie_grup_cat
        foreach (String key in famiglie_grup_cat.Keys)
        {
          String[] vals = key.Split(new char[] { '$' });
          query = "INSERT famiglia_grup_cat (famiglia,gruppo,categoria,num_art) VALUES (" + vals[0] + "," + vals[1] + ","+ vals[2] +"," + famiglie_grup_cat[key] + ")";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }

        // vendors_grup_cat
        foreach (String key in vendors_grup_cat.Keys)
        {
          String[] vals = key.Split(new char[] { '$' });
          query = "INSERT vendor_grup_cat (vendor,gruppo,categoria,num_art) VALUES (" + vals[0] + "," + vals[1] + "," + vals[2] + "," + vendors_grup_cat[key] + ")";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }

        // famiglie_grup_cat_sottocat
        foreach (String key in famiglie_grup_cat_sottocat.Keys)
        {
          String[] vals = key.Split(new char[] { '$' });
          query = "INSERT famiglia_grup_cat_sottocat (famiglia,gruppo,categoria,sottocategoria,num_art) VALUES (" + vals[0] + "," + vals[1] + "," + vals[2] + ","+ vals[3] + "," + famiglie_grup_cat_sottocat[key] + ")";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }

        // vendors_grup_cat_sottocat
        foreach (String key in vendors_grup_cat_sottocat.Keys)
        {
          String[] vals = key.Split(new char[] { '$' });
          query = "INSERT vendor_grup_cat_sottocat (vendor,gruppo,categoria,sottocategoria,num_art) VALUES (" + vals[0] + "," + vals[1] + "," + vals[2] + "," + vals[3] + "," + vendors_grup_cat_sottocat[key] + ")";
          cmd = new SqlCommand(query, connection);
          cmd.Transaction = tr;
          cmd.ExecuteNonQuery();
        }
        
      }
      catch (Exception ex)
      {
        output += "Si è verificato un errore irreversibile durante il caricamento delle tabelle finali di conteggio articoli: " + ex.Message;
        Utility.WriteLog("ERRORE", "CaricaTabellePreCalcolo", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }

    }


    static private Dictionary<String, int> CaricaTab(SqlConnection connection, SqlTransaction tr, Dictionary<String, String[]> dizionario, String tabella, ref String output)
    {
      Dictionary<String, int> dati = new Dictionary<string, int>();
      String query = "";
      SqlCommand cmd;
      int campo = -1;
      
      // Individuo il campo da leggere
      switch (tabella)
      {
        case "famiglia":
          campo=0;
          break;
        case "gruppo":
          campo=1;
          break;
        case "categoria":
          campo=2;
          break;
        case "vendor":
          campo=3;
          break;
        default:
          campo=0;
          break;
      }
      try
      {
        // Per ogni chiave presente nel dizionario
        foreach (String[] vals in dizionario.Values)
        {
          // Controllo se ho già inserito quel dato nella tabella
          String dato = vals[campo];
          if (!dati.ContainsKey(dato))
          {
            // Se non contiene quel dato lo carico
            query = "INSERT INTO "+tabella+" (nome) VALUES ('"+dato+"')";
            cmd = new SqlCommand(query, connection);
            cmd.Transaction = tr;
            cmd.ExecuteNonQuery();

            // Ora leggo dalla tabella l'id del dato appena caricato
            query = "SELECT id FROM " + tabella + " WHERE nome='" + dato + "'";
            cmd = new SqlCommand(query, connection);
            cmd.Transaction = tr;
            int id = Convert.ToInt32(cmd.ExecuteScalar());
            
            // E lo metto nel dizionario
            dati.Add(dato, id);
          }
        }
      }
      catch (Exception ex)
      {
        output += "Si è verificato un errore irreversibile durante il caricamento della tabella "+tabella+": " + ex.Message;
        Utility.WriteLog("ERRORE", "CaricaTab", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }

      return dati;
    }

	
	
    static private Dictionary<String, String[]> ScritturaIndice(SqlConnection connection, SqlTransaction tr, ArrayList arrIndice, ref String output)
    {
        Dictionary<String, String[]> diz = new Dictionary<string, string[]>();


        int count = 0;
        int riga = 0;
        String query = "";

        SqlCommand cmd = null;
        try
        {
            // Elimino il primo elemento che rappresenta i titoli delle colonne
            arrIndice.RemoveAt(0);

            // Per ogni riga dell'indice
            foreach (String str in arrIndice)
            {
                // Incremento il numero di riga
                riga++;
                // Spezzo il listato in campi
                String[] campi = str.Split(new char[] { ';' });
                // Verifico che i campi siano 
                //if (campi.Length != 7)
                if (campi.Length != 6)
                {
                    Utility.WriteLog("ERRORE", "ScritturaIndice", "Riga " + riga + ":la struttura della riga è errata", SiteUser.getUser().Username, str);
                    output += "Si è verificato un errore durante l'elaborazione della riga " + riga + " dell'indice articoli\n";
                    continue;
                }

                // Compongo il codice 
                //String cod = campi[0] + campi[3] + campi[4];
                String cod = campi[3];
                String famiglia = campi[1];
                String gruppo = campi[2];
                String categoria = campi[4];
                String vendor = campi[5];

                // Controllo che le dimensione siano esatte
                if (campi[0].Length != 1)
                {
                    output += "La famiglia indicata nella riga " + riga + " dell'indice è errata\n";
                    Utility.WriteLog("ERRORE", "ScritturaIndice", "La famiglia indicata nella riga " + riga + " dell'indice è errata", SiteUser.getUser().Username, "");
                    throw new Exception("La famiglia indicata nella riga " + riga + " dell'indice è errata");
                }

                if (campi[3].Length != 4)
                {
                    output += "Il gruppo indicato nella riga " + riga + " dell'indice è errata\n";
                    Utility.WriteLog("ERRORE", "ScritturaIndice", "Il gruppo indicato nella riga " + riga + " dell'indice è errata", SiteUser.getUser().Username, "");
                    throw new Exception("Il gruppo indicato nella riga " + riga + " dell'indice è errata");
                }

                /*if (campi[4].Length != 2)
                {
                  output += "La categoria indicata nella riga " + riga + " dell'indice è errata\n";
                  Utility.WriteLog("ERRORE", "ScritturaIndice", "La categoria indicata nella riga " + riga + " dell'indice è errata", SiteUser.getUser().Username, "");
                  throw new Exception("La categoria indicata nella riga " + riga + " dell'indice è errata");
                } */

                // Inserisco nel dizionario
                String[] val = new String[] { famiglia, gruppo, categoria, vendor };
                try
                {
                    diz.Add(cod, val);
                }
                catch (Exception)
                {
                    output += "Il codice categoria prodotto indicato nella riga " + riga + " dell'indice è duplicato\n";
                    Utility.WriteLog("ERRORE", "ScritturaIndice", "Il codice categoria prodotto indicato nella riga " + riga + " dell'indice è duplicato", SiteUser.getUser().Username, "");
                    throw new Exception("La riga " + riga + " dell'indice è errata");
                }

                // Ora scrivo l'articolo riga nel database
                query = "INSERT INTO dizionario(codice,famiglia,gruppo,categoria,vendor) VALUES(";
                query += "'" + cod + "','" + famiglia + "','" + gruppo + "','" + categoria + "','" + vendor + "')";
                cmd = new SqlCommand(query, connection);
                cmd.Transaction = tr;
                cmd.ExecuteNonQuery();
                count++;
            }

            if (count > 0)
            {
                output += "Caricate " + count + " righe nell'indice articoli\n";
            }
            else
            {
                output += "Non è stata individuata alcuna riga valida nel file\n";
                throw new Exception("Nessuna Riga Valida nel file!");
            }
        }
        catch (Exception ex)
        {
            Utility.WriteLog("ERRORE", "ScritturaIndice", ex.Message, SiteUser.getUser().Username, "");
            output += "Si è verificato un errore irreversibile durante l'elaborazione della riga " + riga + " dell'indice articoli\n";
            throw ex;
        }
        return diz;
    }

	///
    static private ArrayList LetturaArticoli(String fileName, ref String output)
    {
      int i = 0;
      StreamReader objReader = null;
      ArrayList arrText = null;
      try
      {
        // Leggo tutte le righe che compongono il file
        objReader = new StreamReader(fileName, System.Text.Encoding.Default);
        String line = "";
        arrText = new ArrayList();
        while (line != null)
        {
          // Se ho letto una line valida 
          line = readLine(objReader);
          if (line != null)
          {
            String cline = clean(line);
            if (cline != null)
              arrText.Add(cline);
            else
            {
              Utility.WriteLog("ERRORE", "LetturaArticoli", "La struttura di una riga del file articoli è errata ed è stata eliminata", SiteUser.getUser().Username, line);
              output += "Errore nella riga " + i + " degli articoli verificarla e ricaricare gli articoli\n";
            }
          }
          i++;
        }
      }
      catch (Exception ex)
      {
        output += "Si è verificato un errore irreversibile durante il caricamento degli articoli: " + ex.Message;
        Utility.WriteLog("ERRORE", "LetturaArticoli", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
      finally
      {
        if (objReader != null) objReader.Close();
      }

      return arrText;
    }

    static private ArrayList LetturaIndice(String fileNameIndice, ref String output)
    {
      int i = 0;
      StreamReader objReader = null;
      ArrayList arrText = null;
      try
      {
        // Leggo tutte le righe che compongono il file
        objReader = new StreamReader(fileNameIndice);
        String line = "";
        arrText = new ArrayList();
        while (line != null)
        {
          // Se ho letto una line valida 
          line = readLine(objReader);
          if (line != null)
          {           
            if (line != null)
              arrText.Add(line);
            else
            {
              Utility.WriteLog("ERRORE", "CaricamentoArticoli", "La struttura di una riga dell'indice è errata ed è stata eliminata", SiteUser.getUser().Username, line);
              output += "Errore nella riga " + i + " dell'indice articoli verificarla e ricaricare gli articoli\n";
            }
          }
          i++;
        }                
      }
      catch (Exception ex)
      {
        output += "Si è verificato un errore irreversibile durante il caricamento dell'indice articoli: " + ex.Message;
        Utility.WriteLog("ERRORE", "LetturaIndice", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
      finally
      {
        if (objReader != null) objReader.Close();
      }

      return arrText;
    }


    static private void CancellaTabelle(SqlConnection connection, SqlTransaction tr,ref String output)
    {
      String query;
      SqlCommand cmd;
      try
      {
        query = "DELETE FROM articolo";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM famiglia";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM vendor";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM gruppo";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM categoria";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM sottocategoria";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM famiglia_gruppo";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM famiglia_grup_cat";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM famiglia_grup_cat_sottocat";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM vendor_gruppo";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM vendor_grup_cat";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM vendor_grup_cat_sottocat";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();

        query = "DELETE FROM dizionario";
        cmd = new SqlCommand(query, connection);
        cmd.Transaction = tr;
        cmd.ExecuteNonQuery();
      }
      catch (Exception ex)
      {
        output += "Si è verificato un errore irreversibile durante la cancellazione delle tabelle: " + ex.Message;
        Utility.WriteLog("ERRORE", "CancellaTabelle", ex.Message, SiteUser.getUser().Username, "");
        throw ex;
      }
    }

    static private void addToCount(ref Dictionary<String, int> toAdd, String key)
    {
      if (toAdd.ContainsKey(key))
      {
        toAdd[key] = toAdd[key] + 1;
      }
      else
      {
        toAdd.Add(key, 1);
      }
    }

    /// <summary>
    /// Versione modificata di lettura da file in cui il \n o \r da soli non vengono considerati come fine linea
    /// il metodo è piuttosto lento ma non ci sono alternative....
    /// </summary>
    /// <param name="rd"></param>
    /// <returns></returns>
    static private String readLine(StreamReader rd)
    {
      String toRet = null;
      char ch;
      try
      {
        while (true)
        {            
          int val = rd.Read();
          if (val == -1) break;         
          ch = Convert.ToChar(val);
          if (ch == '\r') { rd.Read(); break; }
          toRet += ch;
        }
      }
      catch (Exception) { }

      return toRet;
    }

    /// <summary>
    /// Questo metodo prende una riga in cui potrebbe esserci scritto dell'html e la prepara per la separazione
    /// (sostiuisce "" con " singolo, sostituisce ; con $semicolon$ e toglie gli apici iniziali)
    /// </summary>
    /// <param name="line"></param>
    /// <returns></returns>
    static private String clean(String line)
    {
      String toRet = "";
      String toAnal = line;

      toAnal = toAnal.Replace("\"\"", "$apice$");

      // Cerco le porzioni di testo che potrebbero contenere valori inadeguati
      int pos1 = toAnal.IndexOf("\"");
      while (pos1 != -1)
      {
        int pos2 = toAnal.IndexOf("\"", pos1 + 1);
        if (pos2 != -1)
        {
          String toClean = toAnal.Substring(pos1, pos2 - pos1 + 1);
          toClean = toClean.Replace(";", "$semicolon$");
          toClean = toClean.Replace("\"", "");
          toAnal = toAnal.Substring(0, pos1) + toClean + toAnal.Substring(pos2 + 1, toAnal.Length - pos2 - 1);
        }
        else
          return null;
        pos1 = toAnal.IndexOf("\"");
      }

      toRet = toAnal.Replace("$apice$", "\"");
      return toRet;

    }   
  }
}